﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace InputBoxes.Controls
{
    public partial class InputBoxBase : UserControl
    {
        protected readonly Color DefaultEditorBackColor = Color.FromKnownColor(KnownColor.Window);
        protected readonly Color ValidEditorBackColor = Color.GreenYellow;
        protected readonly Color InvalidEditorBackColor = Color.Red;
        private bool _mustHaveValue;
        private Control _editor;

        public InputBoxBase()
        {
            InitializeComponent();
            Load += InputBoxBase_Load;
            FontChanged += StaticTextChanged;
        }

        public StaticTextInfo LeftInfo { get { return LeftTextBox.Info; } set { LeftTextBox.Info = value; } }
        public StaticTextInfo RightInfo { get { return RightTextBox.Info; } set { RightTextBox.Info = value; } }

        public bool MustHaveValue
        {
            get { return _mustHaveValue; }
            set
            {
                _mustHaveValue = value;
                PerformValidate();
            }
        }

        [Browsable(false)]
        public object UntypedValue
        {
            get { return GetUntypedValue(); }
            set { SetUntypedValue(value); }
        }

        public void PerformValidate()
        {
            bool isValid = GetIsValid();
            SetBackColor(isValid, GetEditor().Focused);
        }

        internal void StaticTextChanged(object sender, EventArgs e)
        {
            IStaticTextBox textBox = sender as IStaticTextBox;
            if (textBox == null) return;

            int width = textBox.Info.Visible ? textBox.CalculateWidth() : 0;
            LayoutPanel.ColumnStyles[LayoutPanel.GetColumn((Control)textBox)].Width = width;
        }

        internal void StaticTextChanged()
        {
            StaticTextChanged(LeftTextBox, EventArgs.Empty);
            StaticTextChanged(RightTextBox, EventArgs.Empty);
        }

        protected Control GetEditor()
        {
            return _editor;
        }

        protected bool GetIsValid()
        {
            return GetIsValid(Text);
        }

        protected void SetEditor(Control editor)
        {
            _editor = editor;
            LayoutPanel.Controls.Add(editor);
            LayoutPanel.SetColumn(editor, 1);
            LayoutPanel.SetRow(editor, 0);
        }

        protected virtual bool GetIsValid(string text)
        {
            return !MustHaveValue || !string.IsNullOrEmpty(text);
        }

        protected virtual object GetUntypedValue()
        {
            return null;
        }

        protected virtual void SetUntypedValue(object value)
        {
        }

        private void SetBackColor(bool isValid, bool focused)
        {
            GetEditor().BackColor = focused
                                         ? (isValid
                                                ? ValidEditorBackColor
                                                : InvalidEditorBackColor)
                                         : DefaultEditorBackColor;
        }

        private void InputBoxBase_Load(object sender, EventArgs e)
        {
            GetEditor().BackColor = DefaultEditorBackColor;
        }

        private void InputBoxBase_BackColorChanged(object sender, EventArgs e)
        {
            LeftTextBox.BackColor = RightTextBox.BackColor = BackColor;
        }
    }
}
